﻿using Ivi.Visa;
using NationalInstruments.Visa;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using static System.Net.Mime.MediaTypeNames;

namespace CSharpTest_OSC
{
    public class Siglent_Digital_Oscilloscope : Digital_Oscilloscope,IReadWaveForm
    {
        private Single VerticalGain { get; set; } // VerticalGain
        private Single VerticalOffset {  get; set; }   // Offset
        private Single ProbeAttenuation { get; set; } // 探头增益
        private Single CodelPerDiv { get; set; }   // 


        public void readWaveform(MessageBasedSession mbSession)
        {
            string channalName = "C1";
            mbSession.RawIO.Write($":WAV:SOUR {channalName};:WAVeform:PREamble?;:WAV:MAXPoint?");
            byte[] chInfo = mbSession.RawIO.Read(393);

            byte[] _parseDoubleBytes = new byte[4];
            Array.Copy(chInfo, 167, _parseDoubleBytes, 0, 4); // 复制指定四个字节用来转换成Single
            _parseDoubleBytes.Reverse();
            VerticalGain = BitConverter.ToSingle(_parseDoubleBytes, 0);

            Array.Copy(chInfo, 171, _parseDoubleBytes, 0, 4); // 复制指定四个字节用来转换成Single
            _parseDoubleBytes.Reverse();
            VerticalOffset = BitConverter.ToSingle(_parseDoubleBytes, 0);

            Array.Copy(chInfo, 175, _parseDoubleBytes, 0, 4); // 复制指定四个字节用来转换成Single
            _parseDoubleBytes.Reverse();
            CodelPerDiv = BitConverter.ToSingle(_parseDoubleBytes, 0);

            Array.Copy(chInfo, 339, _parseDoubleBytes, 0, 4); // 复制指定四个字节用来转换成Single
            _parseDoubleBytes.Reverse();
            ProbeAttenuation = BitConverter.ToSingle(_parseDoubleBytes, 0);

            mbSession.RawIO.Write("TRIG:STOP");
            mbSession.RawIO.Write($"WAV:SOUR {channalName}");

            int readOffset = 0;

            List<byte> rawWaveData = new List<byte> { };
            List<byte> tmpData = new List<byte> { };
            do
            {
                ReadStatus readStatus = ReadStatus.Unknown;
                tmpData.Clear();
                mbSession.RawIO.Write($"WAV:STAR {readOffset}");
                mbSession.RawIO.Write(@":WAV:DATA?;");
                while (readStatus != ReadStatus.EndReceived)
                {
                    tmpData.AddRange(mbSession.RawIO.Read(4096, out readStatus));
                }
                rawWaveData.AddRange(tmpData);
                readOffset += tmpData.Count;
            } while (tmpData.Count >= 40);

            byte[] header = Encoding.UTF8.GetBytes("#9");
            int headerIndex = FindSequence(rawWaveData, header);

            if (rawWaveData.Count < 100)
                return;

            short[] I16WaveData = new short[(rawWaveData.Count - headerIndex - 40) /2];
            //Buffer.BlockCopy(byteArray, 0, shortArray, 0, byteArray.Length);
            byte[] rawWaveDataNoHeader = rawWaveData.GetRange(headerIndex + 11, rawWaveData.Count - headerIndex - 40).ToArray(); //注意丢掉了最后一个元素！以及最后一句 fp > current memory depth!
            Buffer.BlockCopy(rawWaveDataNoHeader, 0, I16WaveData, 0, rawWaveDataNoHeader.Length);

            Single[] wavData = new Single[I16WaveData.Count()];
            for (int i = 0; i < I16WaveData.Length; i++)
            {
                wavData[i] = (I16WaveData[i] * VerticalGain / CodelPerDiv - VerticalOffset) * ProbeAttenuation;
            }

            /*
            string filePath = "waveformdata.txt";
            using (StreamWriter writer = new StreamWriter(filePath))
            {
                for (int i = 0; i < wavData.Length; i++)
                {
                    // 将每个元素写入文件，并在每个元素后添加换行符
                    writer.WriteLine(wavData[i]);
                }
            }
            */

            Console.WriteLine("read waveform Done!");

        }

        public override void snapShot(MessageBasedSession mbSession)
        {
            var start = DateTime.Now;

            mbSession.RawIO.Write("PRIN? PNG");
            List<byte> tmpData = new List<byte> { };
            ReadStatus readStatus = ReadStatus.Unknown;
            while (readStatus != ReadStatus.EndReceived)
            {
                tmpData.AddRange(mbSession.RawIO.Read(1024, out readStatus));
            }

            string filePath = "temp.png";
            using (FileStream fileStream = new FileStream(filePath, FileMode.Create))
            {
                fileStream.Write(tmpData.ToArray(), 0, tmpData.Count);
            }

            var stop = DateTime.Now;
            Console.WriteLine($"程序耗时：{(stop - start).TotalMilliseconds}ms.");
        }

        public static int FindSequence(List<byte> list, byte[] sequence)
        {
            if (sequence.Length == 0)
            {
                return 0; // 空序列被认为是在列表开始处找到
            }

            for (int i = 0; i <= list.Count - sequence.Length; i++)
            {
                bool match = true;
                for (int j = 0; j < sequence.Length; j++)
                {
                    if (list[i + j] != sequence[j])
                    {
                        match = false;
                        break;
                    }
                }
                if (match)
                {
                    return i; // 返回匹配的起始索引
                }
            }
            return 0; // 没有找到匹配项
        }

        public static List<short> ConvertToShortList(List<byte> list)
        {
            List<short> shortList = new List<short>();
            for (int i = 0; i < list.Count; i += 2)
            {
                // 假设字节序为小端
                short shortValue = BitConverter.ToInt16(list.ToArray(), i);
                shortList.Add(shortValue);
            }
            return shortList;
        }
    }

}
